#ifndef AWINIC_AUDIO_H
#define AWINIC_AUDIO_H

#include <stdint.h>

/****************DATA EXPANDER and COMPRESS SET*****************************************/
#define  DAT_CPR_BIT  (5)              //in_data compress bit (23 - 18)
#define  DAT_CPR      (32)            //Compress 2^DAT_CPR_BIT 
#define  IN_DAT_BIT      (18)

#define  COE_EXP_BIT  20
#define  COE_EXP      1048576          //2^COE_EXP_BIT  Coefficient Expansion factor
#define  COE_EXP_NEG  (-1048576)
#define  COE_EXP_MAX  1048575          // 2^COE_EXP_BIT - 1

#define  DAT_EXP_BIT  31
#define  DAT_EXP      2147483648ULL      //2^DAT_EXP_BIT
#define  MAX_31B      0x7fffffff         //2^DAT_EXP_BIT -1
#define  DAT_EXP_NEG  (-2147483648ULL)

#define  SIZE_1K      1024

#define INIT_GAIN_EXP_BIT (4)
#define INIT_GAIN_EXP (16)

/**************** audio data  set end **************************************************/

/**************** FILTER SETTING START *************************************************/
#define FT_COE_NUM 5
#define FT_DATA_NUM 2
#define FT_NUM      3
#define CHANNEL_MAX 2
#define EX_GAIN_EXP (16777216)
#define EX_GAIN_EXP_BIT (24)

//fiter relate coe and data struct
typedef struct filter_coe{
	int32_t index[FT_COE_NUM];
}ft_coe_t;
typedef struct filter_data{
	int32_t indata[FT_DATA_NUM];
	int32_t outdata[FT_DATA_NUM];
}ft_dat_t;

typedef struct filter_cfg{
	ft_coe_t coe;
	ft_dat_t data;
}ft_cfg_t;

typedef struct ExcursionMode{
    int32_t gain;
	ft_cfg_t ft_cfg[FT_NUM];
}ex_cfg_t;
typedef struct ExcursionModeCoe{
    int32_t gain;
    ft_coe_t ft_coe[FT_NUM];
}ex_coe_t;
/**************** FILTER SETTING END *************************************************/
#define  DEC_NUM  (2)
#define  DEC_NUMBER (8)
#define  DEC_ENABLE_MASK (0x01)
#define  DEC_ENABLE (0X01)

typedef struct DecmiateModule{
    int32_t gain;
    ft_cfg_t ft_cfg[DEC_NUM];
}dec_cfg_t;

typedef struct DecmiateCoe{
    int32_t gain;
    ft_coe_t ft_coe[DEC_NUM];
}dec_coe_t;

/**************** PEAK DETECTOR SET START *******************************************/
typedef struct PeakDetectCoe{
	  int32_t AlphaAttr;           //attrack index
	  int32_t AlphaRel;            //release index
      int32_t Hold_Attr;           //attrack step
	  int32_t Hold_Rel;            //release step
}pd_coe_t;

typedef struct PeakDetectData{
      int32_t hold_cnt_att;     // left hold Count
      int32_t hold_cnt_rel;     // right channel release count
	  int32_t comb;             // store left data peak
      int32_t section_peak;
      int32_t data_count;
}pd_data_t;

typedef struct Peak_Detect_Cfg{
       pd_coe_t  coe;
       pd_data_t data;
}pd_cfg_t;
/**************** PEAK DETECTOR SET END *******************************************/

/**************** GAIN COMPUTER SET START *******************************************/
#define GC_ALGO_MAX      1                     //Gain computer cfg number

#define GainFF_EXP_BIT   20                    //16   //GainFF Expansion BIT
#define GainFF_EXP       1048576               //65536 //2^GainFF_EXP_BIT
#define GainFF_EXP_NEG   (-1048576)            //(-65536)    //(-1048576)

#define GainFF_Coe       ((int32_t)20971520)   //1310720     //20*2^GainFF_EXP_BIT
#define GainFF_Sub       (5.418783187866211)  //9469585     // 20 log(2^(DAT_EXP_BIT-DAT_CPR_BIT))
#define Min_Limit        1                    // 1e-6 * 2^(DAT_EXP_BIT-DAT_CPR_BIT)

#define COMPRESS  1
#define EXPANDER  2
#define NOISEGAT  3
#define HARDHALF  0

typedef struct GainCureCoe{
      int32_t threshold;          // overshoot base line
      int32_t ratio;
	  int32_t knee;
      int32_t Slope;              //Feed-forward topology
      int32_t Width;              //overshoot width
      int32_t GainCoe;            //Coefficient
}gainff_coe_t;

typedef struct Gain_Cure_Cfg{
    gainff_coe_t coe;
    int32_t mode;
}gainff_cfg_t;
/**************** GAIN COMPUTER SET END *******************************************/

/**************** GAIN SMOOTH SETTING START ***************************************/
#define CONVERT_FLOAT        (0.0000000476837158203125)
#define BETA_CONSANT      (1.12)
#define GS_DAT_EXP     (2147483648ULL)
#define GS_DAT_EXP_BIT (31)
#define GS_DAT_MAX     (0x7fffffff)


typedef struct GainSmoothCoe{
      int32_t AlphaAttr;          //attrack index
	  int32_t AlphaRel;           //release index
}gs_coe_t;
typedef struct GainSmoothData{
      int32_t state;
      int32_t beta;
}gs_data_t;
typedef struct Gain_Smooth_Cfg{
	gs_coe_t coe;
	gs_data_t data;
}gs_cfg_t;
/**************** GAIN SMOOTH SETTING START ***************************************/

/**************** ExcursionMode Limiter Struct *********************************/
typedef struct MemExLimiterCfg{
    dec_cfg_t dec_cfg;
	ex_cfg_t ex_cfg;
	pd_cfg_t pd_cfg;
	gainff_cfg_t gain_cfg;
	gs_cfg_t gs_cfg;
}Mem_Cfg_t;
typedef struct AwinicAlgoCoe{
    uint32_t modenable;
    dec_coe_t dec_coe;
    ex_coe_t ex_coe;
    pd_coe_t pd_coe;
    gainff_cfg_t gain_cfg;
    gs_coe_t gs_coe;
}aw_coe_t;
/***************** ExcursionMode Limiter Struct *********************************/


/***************** Voltage Limiter struct ***************************************/
typedef struct VoltageLimiterCfg{
	pd_cfg_t pd_cfg;
	gainff_cfg_t gain_cfg;
	gs_cfg_t gs_cfg;
}Vol_Cfg_t;
typedef struct VoltageLimiterCoe{
    pd_coe_t pd_coe;
    gainff_cfg_t gain_cfg;
    gs_coe_t gs_coe;
}Vol_Coe_t;
/**************** Voltage Limiter struct ****************************************/

/**************** Algo Config struct ********************************************/
#define SHIFT_MAX   (2500)
#define BUFFER_MAX  (1024+2)
typedef struct awinic_algo_cfg{
	uint32_t init_gain;
	uint32_t scale_gain;
	int32_t Shift_Num;
    uint32_t modenable;
    Mem_Cfg_t mem_cfg;
	Vol_Cfg_t    vol_cfg;
    int32_t shift_buffer[SHIFT_MAX];
    int32_t temp_buffer[BUFFER_MAX];
}aw_algo_cfg_t;
/**************** Algo Config struct ********************************************/

typedef struct awinic_read_cfg{
	uint32_t init_gain;
	uint32_t scale_gain;
    int32_t xmax_threshold;
    int32_t vmax_threshold;
	int32_t Shift_Num;
	aw_coe_t aw_algo_coe;
}aw_read_cfg_t;
/**************** InterFace Function for EXTERN *********************************/
void AwinicAlgoInit(void*cfg_ptr);
int32_t AwinicAudioHandle(void *buffer,ssize_t bytes,void *cfg_ptr);
void AwinicAlgoDeinit(void*cfg_ptr);
void AwinicAlgoClear(void*cfg_ptr);
ssize_t AwinicGetSize(void);
#endif
